package com.winai.launcher.manager;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.text.TextUtils;

import com.aiyisheng.speaker.main.IBinderPool;
import com.aiyisheng.speaker.main.IDuiObserver;
import com.aiyisheng.speaker.main.IDuiSpeechListener;
import com.aiyisheng.speaker.main.ILauncherInterface;
import com.ks.projectbasictools.utils.LogUtils;
import com.winai.launcher.constant.Constant;
import com.winai.launcher.interfaces.OnAiyishengVersionCallbackListener;

/**
 * @author kangshao
 * @date 2020/9/23
 * @desc 艾益生 AIDL管理器
 */
public class AiyishengManager {
    private static AiyishengManager mInstance;
    private Context mContext;

    private Intent serviceIntent;
    private ServiceConnection connection;
    private ILauncherInterface iLauncherInterface = null;
    private IDuiObserver iDuiObserver = null;
    private IBinderPool iBinderPool;

    public static AiyishengManager getInstance(Context context) {
        if (mInstance == null) {
            synchronized (AiyishengManager.class) {
                if (mInstance == null) {
                    mInstance = new AiyishengManager(context.getApplicationContext());
                }
            }
        }
        return mInstance;
    }

    public AiyishengManager() {
        try {
            throw new Exception("AiyishengManager 单例模式不允许实例化");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private AiyishengManager(Context mContext) {
        this.mContext = mContext;
        serviceIntent = new Intent();
        serviceIntent.setComponent(new ComponentName("com.aiyisheng.speaker", "com.aiyisheng.speaker.main.aidl.AIDLService"));
        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                try {
                    //设置死亡代理
                    iBinder.linkToDeath(deathRecipient, 0);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                initIBinder(iBinder);
            }

            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                LogUtils.e("Aiyisheng的service连接断开");
            }
        };
        bindServiceByAidl();
    }

    private IBinder.DeathRecipient deathRecipient = new IBinder.DeathRecipient() {
        @Override
        public void binderDied() {
            LogUtils.e("binderDied!");
            //解绑
            if (iLauncherInterface != null) {
                iLauncherInterface.asBinder().unlinkToDeath(deathRecipient, 0);
                iLauncherInterface = null;
            }
            //解绑
            if (iDuiObserver != null) {
                iDuiObserver.asBinder().unlinkToDeath(deathRecipient, 0);
                iDuiObserver = null;
            }

            //断开重新绑定
            bindServiceByAidl();
        }
    };

    private void initIBinder(IBinder iBinder) {
        iBinderPool = IBinderPool.Stub.asInterface(iBinder);
        try {
            iLauncherInterface = ILauncherInterface.Stub.asInterface(iBinderPool.queryBinder(2));
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        LogUtils.e("Aiyisheng的service连接成功,iLauncherInterface = " + iLauncherInterface);

        try {
            iDuiObserver = IDuiObserver.Stub.asInterface(iBinderPool.queryBinder(1));
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        LogUtils.e("Aiyisheng的service连接成功,iDuiObserver = " + iDuiObserver);

        initListener();
    }

    private void initListener() {
        try {
            iDuiObserver.setOnSpeechListener(new IDuiSpeechListener.Stub() {
                @Override
                public void onStartSpeak(String content, String ttsId) throws RemoteException {
                    ttsSpeak(content, ttsId, "start");
                }

                @Override
                public void onStopSpeak(String ttsId) throws RemoteException {
                    ttsSpeak(null, ttsId, "stop");
                }

                @Override
                public void onStartRecognition(String content, String ttsId) throws RemoteException {
                    ttsDialog(content, ttsId, "start");
                }

                @Override
                public void onStopRecognition(String ttsId) throws RemoteException {
                    ttsDialog(null, ttsId, "stop");
                }

                @Override
                public void onListeningState(int state) throws RemoteException {
                    asrListening(state);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void bindServiceByAidl() {
        LogUtils.e("bindServiceByAidl!");
        try {
            mContext.bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @date 2020/9/28
     * @desc iLauncherInterface是否存活
     */
    public boolean iLauncherInterfaceIsAlive() {
        if (iLauncherInterface == null) {
            return false;
        }
        return iLauncherInterface.asBinder().isBinderAlive();
    }

    /**
     * @date 2020/12/02
     * @desc iDuiObserver是否存活
     */
    public boolean iDuiObserverIsAlive() {
        if (iDuiObserver == null) {
            return false;
        }
        return iDuiObserver.asBinder().isBinderAlive();
    }

    public void unbindServiceByAidl() {
        try {
            mContext.unbindService(connection);
            iLauncherInterface = null;
            iDuiObserver = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    int count = 0;

    /**
     * @date 2020/9/21
     * @desc 打开艾益生页面
     */
    public void startAiyishengAct(String routerPath) {
        if (iLauncherInterfaceIsAlive()) {
            count = 0;
            LogUtils.e("binder连接成功，正在打开艾益生页面");
            try {
                iLauncherInterface.openActivity(routerPath);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("binder为没有连接,正在尝试第" + count + "次重新连接");
            bindServiceByAidl();
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    startAiyishengAct(routerPath);
                }
            }, 200);
        } else {
            count = 0;
            LogUtils.e("binder连接失败");
        }
    }

    /**
     * @date 2020/9/21
     * @desc 为语音打开某个页面方法
     */
    public void intentActivity(String command, String data, boolean isNative) {
        if (iLauncherInterfaceIsAlive()) {
            count = 0;
            LogUtils.e("binder连接成功，正在打开艾益生页面-语音");
            try {
                iLauncherInterface.intentActivity(command, data, isNative);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("binder为没有连接,正在尝试第" + count + "次重新连接");
            bindServiceByAidl();
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    intentActivity(command, data, isNative);
                }
            }, 200);
        } else {
            LogUtils.e("binder连接失败");
            count = 0;
        }
    }

    /**
     * @date 2020/10/12
     * @desc 获取艾益生版本号
     */
    public void getAiyishengVisionCode(OnAiyishengVersionCallbackListener listener) {
        if (iLauncherInterfaceIsAlive()) {
            count = 0;
            LogUtils.e("binder连接成功，获取艾益生版本号");
            try {
                String appVisionCode = iLauncherInterface.getAppVisionCode();
                listener.onSuccess(appVisionCode);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("binder为没有连接,正在尝试第" + count + "次重新连接");
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    getAiyishengVisionCode(listener);
                }
            }, 200);
        } else {
            LogUtils.e("binder连接失败");
            count = 0;
            listener.onError();
        }
    }

    /**
     * @param listener
     * @date 2020/10/12
     * @desc 获取艾益生版本号
     */
    public void getAiyishengVisionName(OnAiyishengVersionCallbackListener listener) {
        if (iLauncherInterfaceIsAlive()) {
            count = 0;
            LogUtils.e("iLauncherInterface连接成功，获取艾益生版本名称");
            try {
                String appVisionName = iLauncherInterface.getAppVisionName();
                listener.onSuccess(appVisionName);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("iLauncherInterface为没有连接,正在尝试第" + count + "次重新连接");
            bindServiceByAidl();
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    getAiyishengVisionName(listener);
                }
            }, 200);
        } else {
            LogUtils.e("iLauncherInterface连接失败");
            count = 0;
            listener.onError();
        }
    }

    public void onMessageCall(String message, String data, String resourceVersion) {
        if (iDuiObserverIsAlive()) {
            count = 0;
            LogUtils.e("iDuiObserver连接成功，通知艾益生AI的MessageCall");
            try {
                iDuiObserver.onMessageCall(message, data, resourceVersion);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("iDuiObserver为没有连接,正在尝试第" + count + "次重新连接");
            bindServiceByAidl();
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    onMessageCall(message, data, resourceVersion);
                }
            }, 200);
        } else {
            LogUtils.e("iDuiObserver连接失败");
            count = 0;
        }
    }

    public void onCommandCall(String command, String data, String resourceVersion) {
        if (iDuiObserverIsAlive()) {
            count = 0;
            LogUtils.e("iDuiObserver连接成功，通知艾益生AI的CommandCall");
            try {
                iDuiObserver.onCommandCall(command, data, resourceVersion);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("iDuiObserver为没有连接,正在尝试第" + count + "次重新连接");
            bindServiceByAidl();
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    onCommandCall(command, data, resourceVersion);
                }
            }, 200);
        } else {
            LogUtils.e("iDuiObserver连接失败");
            count = 0;
        }
    }

    /**
     * @desc 主动开启识别并播报内容
     */
    public void onStartRecognition() {
        if (iDuiObserverIsAlive()) {
            count = 0;
            LogUtils.e("iDuiObserver连接成功，通知艾益生AI的StartRecognition");
            try {
                iDuiObserver.onStartRecognition();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("iDuiObserver为没有连接,正在尝试第" + count + "次重新连接");
            bindServiceByAidl();
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    onStartRecognition();
                }
            }, 200);
        } else {
            LogUtils.e("iDuiObserver连接失败");
            count = 0;
        }
    }

    /**
     * @desc 主动开启识别并播报内容
     */
    public void onSpeakEnd(String ttsId) {
        if (iDuiObserverIsAlive()) {
            count = 0;
            LogUtils.e("iDuiObserver连接成功，通知艾益生AI的onSpeakEnd");
            try {
                iDuiObserver.onSpeakEnd(ttsId);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("iDuiObserver为没有连接,正在尝试第" + count + "次重新连接");
            bindServiceByAidl();
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    onStartRecognition();
                }
            }, 200);
        } else {
            LogUtils.e("iDuiObserver连接失败");
            count = 0;
        }
    }

    /**
     * @desc 关闭识别
     */
    public void onStopRecognition() {
        if (iDuiObserverIsAlive()) {
            count = 0;
            LogUtils.e("iDuiObserver连接成功，通知艾益生AI的onStopRecognition");
            try {
                iDuiObserver.onStopRecognition();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("iDuiObserver为没有连接,正在尝试第" + count + "次重新连接");
            bindServiceByAidl();
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    onStopRecognition();
                }
            }, 200);
        } else {
            LogUtils.e("iDuiObserver连接失败");
            count = 0;
        }
    }

    /**
     * @desc ASR主动识别结果回调 methodName 需要回调的方法名  content 识别到的内容
     */
    public void onListeningResult(String methodName, String content) {
        if (iDuiObserverIsAlive()) {
            count = 0;
            LogUtils.e("iDuiObserver连接成功，通知艾益生语音主动识别结果onListeningResult");
            try {
                iDuiObserver.onListeningResult(methodName, content);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if (count < 5) {
            count++;
            LogUtils.e("iDuiObserver为没有连接,正在尝试第" + count + "次重新连接");
            bindServiceByAidl();
            new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                @Override
                public void run() {
                    onStopRecognition();
                }
            }, 200);
        } else {
            LogUtils.e("iDuiObserver连接失败");
            count = 0;
        }
    }

    /**
     * @param content 播报内容
     * @param ttsId   播报的ttsId
     * @param type    start，开始播报；stop，停止播报
     * @desc 广播通知语音播报或停止播报
     */
    private void ttsSpeak(String content, String ttsId, String type) {
        Intent intent = new Intent();
        intent.setAction(Constant.action_aiyisheng_text_speech);
        if (!TextUtils.isEmpty(content)) {
            intent.putExtra("content", content);
        }
        if (!TextUtils.isEmpty(ttsId)) {
            intent.putExtra("ttsId", ttsId);
        }
        if (!TextUtils.isEmpty(type)) {
            intent.putExtra("type", type);
        }
        mContext.sendBroadcast(intent);
    }

    /**
     * @param content 播报内容
     * @param ttsId   播报的ttsId
     * @param type    start，开始播报；stop，停止播报
     * @desc 广播通知IP形象对话打开或关闭
     */
    private void ttsDialog(String content, String ttsId, String type) {
        Intent intent = new Intent();
        intent.setAction(Constant.action_aiyisheng_dialog);
        if (!TextUtils.isEmpty(content)) {
            intent.putExtra("content", content);
        }
        if (!TextUtils.isEmpty(ttsId)) {
            intent.putExtra("ttsId", ttsId);
        }
        if (!TextUtils.isEmpty(type)) {
            intent.putExtra("type", type);
        }
        mContext.sendBroadcast(intent);
    }

    /**
     * 主动识别控制
     *
     * @param state 0：停止识别；1：开始识别；2：取消识别
     */
    private void asrListening(int state) {
        Intent intent = new Intent();
        intent.setAction(Constant.action_aiyisheng_listening_control);
        intent.putExtra("state", state);
        mContext.sendBroadcast(intent);
    }
}
